package com.example.friend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.core.constants.Constants;
import com.example.core.domain.TableDataInfo;
import com.example.core.enums.ExamListType;
import com.example.friend.domain.Exam;
import com.example.friend.domain.UserExam;
import com.example.friend.domain.UserSubmit;
import com.example.friend.domain.dto.ExamDTO;
import com.example.friend.domain.dto.ExamQuestionDTO;
import com.example.friend.domain.vo.ExamBaseInfo;
import com.example.friend.elasticsearch.QuestionRepository;
import com.example.friend.manger.ExamCacheManager;
import com.example.friend.manger.QuestionCacheManager;
import com.example.friend.mapper.ExamMapper;
import com.example.friend.mapper.UserExamMapper;
import com.example.friend.mapper.UserSubmitMapper;
import com.example.friend.service.IExamService;
import com.example.scurity.exception.ServiceException;
import com.example.scurity.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;

@Service
public class ExamServiceImpl implements IExamService {

    @Autowired
    private UserExamMapper userExamMapper;
    @Autowired
    private UserSubmitMapper userSubmitMapper;
    @Autowired
    private QuestionCacheManager questionCacheManager;
    @Autowired
    private QuestionRepository questionRepository;
    @Autowired
    private ExamCacheManager examManager;

    @Autowired
    private ExamMapper examMapper;

    @Override
    public TableDataInfo list(ExamDTO examDTO) {
        //分页参数
        int start = (examDTO.getPageNum() - 1) * examDTO.getPageSize();
        int end = start + examDTO.getPageSize();
        if (ExamListType.EXAM_NOT_STARTED_LIST.getValue().equals(examDTO.getExamStatus())) {
            return examManager.selectExamList(start, end, SecurityUtils.getUserId(), examDTO.getQStartTime(), examDTO.getQEndTime());
        } else if (ExamListType.EXAM_HISTORY_LIST.getValue().equals(examDTO.getExamStatus())) {
            return examManager.selectHistoryExamList(start, end, SecurityUtils.getUserId());
        }
        return TableDataInfo.empty();
    }


    @Override
    public TableDataInfo selectHistoryExamList(ExamDTO searchDTO) {
        //分页参数
        int start = (searchDTO.getPageNum() - 1) * searchDTO.getPageSize();
        int end = start + searchDTO.getPageSize();
        return examManager.selectHistoryExamList(start, end, SecurityUtils.getUserId());
    }

    @Override
    public TableDataInfo examQuestionList(ExamQuestionDTO examQuestionDTO) {
        //分页参数
        int start = (examQuestionDTO.getPageNum() - 1) * examQuestionDTO.getPageSize();
        int end = start + examQuestionDTO.getPageSize();
        return questionCacheManager.selectExamQuestionList(questionRepository, examQuestionDTO.getExamId(), start, end);
    }


    @Override
    public Exam getById(Long examId) {
        //直接操作数据库
        return examMapper.selectById(examId);
    }

    @Override
    public int submit(Long examId) {
        //提交后计算得分的方式，大并发情况下会引发性能问题。
        //需要判断是否还有未提交的题目
        //用户提交竞赛后只在缓存中记录用户已经将竞赛提交。
        //提交后  计算总得分  未查到题目提交记录的按0分计算
        Long userId = SecurityUtils.getUserId();
        List<UserSubmit> userSubmitList = userSubmitMapper.selectList(new LambdaQueryWrapper<UserSubmit>()
                .eq(UserSubmit::getExamId, examId)
                .eq(UserSubmit::getUserId, userId));
        UserExam userExam = userExamMapper.selectOne(new LambdaQueryWrapper<UserExam>()
                .eq(UserExam::getExamId, examId)
                .eq(UserExam::getUserId, userId));
        if (userExam == null) {
            throw new ServiceException("未获取到用户参赛信息");
        }
        userExam.setSubmit(Constants.TRUE);
        userExam.setSubmitTime(LocalDateTime.now());
        int score = 0;
        //提交记录不为空计算总分
        if (!CollectionUtils.isEmpty(userSubmitList)) {
            for (UserSubmit userSubmit : userSubmitList) {
                score += userSubmit.getScore();
            }
        }
        userExam.setScore(score);
        return userExamMapper.updateById(userExam);
    }

    @Override
    public TableDataInfo rankList(ExamDTO examDTO) {
        //分页参数
        int start = (examDTO.getPageNum() - 1) * examDTO.getPageSize();
        int end = start + examDTO.getPageSize();
        return examManager.rankList(start, end, examDTO.getExamId());
    }

    @Override
    public ExamBaseInfo baseInfo(Long examId) {
        Exam exam = examManager.selectExamBaseInfo(examId);
        ExamBaseInfo baseInfo = new ExamBaseInfo();
        BeanUtils.copyProperties(exam, baseInfo);
        return baseInfo;
    }

}
